package com.humh.util;


import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 日期工具类，用于处理日期和时间，包括调整到工作时间范围内等。
 * 说明：
 *    adjustToWorkHours 方法：检查是否为周末或节假日，如果是，则调整到下一个工作日的开始时间（9点）。
 *    isHoliday 方法：这是一个简单的示例方法，实际应用中应该有一个可靠的方式来确定哪些日子是节假日。
 * 在这个示例中，假设所有10月4日为节假日。
 *    getNextWorkingDay 方法：找到给定日期之后的第一个工作日。
 * 你可以根据实际情况替换isHoliday方法中的逻辑，以便正确识别法定节假日。如果你有具体的节假日列表，
 * 可以通过配置文件、数据库查询等方式来实现这个功能。
 */
public class DateUtils {
  public static void main(String[] args) {
    // 示例：定义开始和结束时间
    LocalDateTime startTime = LocalDateTime.of(2024, 10, 1, 14, 0);
    LocalDateTime endTime = LocalDateTime.of(2024, 10, 9, 19, 0);

    // 调整到工作时间范围内
    LocalDateTime adjustedStartTime = adjustToWorkHours(startTime);
    LocalDateTime adjustedEndTime = adjustToWorkHours(endTime);

    System.out.println("原始开始时间: " + startTime);
    System.out.println("调整后的开始时间: " + adjustedStartTime);
    System.out.println("原始结束时间: " + endTime);
    System.out.println("调整后的结束时间: " + adjustedEndTime);
  }

  /**
   * 调整日期和时间，使其在9点到17点之间，并排除周末和节假日。
   * @param dateTime
   * @return
   */
  private static LocalDateTime adjustToWorkHours(LocalDateTime dateTime) {
    LocalDate date = dateTime.toLocalDate();
    DayOfWeek dayOfWeek = date.getDayOfWeek();
    LocalTime time = dateTime.toLocalTime();

    if (dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY || isHoliday(date)) {
      // 如果是周末或节假日，调整到下一个工作日的开始时间
      date = getNextWorkingDay(date);
      return LocalDateTime.of(date, LocalTime.of(9, 0));
    } else if (time.isBefore(LocalTime.of(9, 0))) {
      // 如果时间早于9点，调整到当天的9点
      return LocalDateTime.of(date, LocalTime.of(9, 0));
    } else if (time.isAfter(LocalTime.of(17, 0))) {
      // 如果时间晚于17点，调整到当天的17点
      return LocalDateTime.of(date, LocalTime.of(17, 0));
    } else {
      // 否则保持原样
      return dateTime;
    }
  }

  /**
   * 判断给定的日期是否为节假日。
   * @param date
   * @return
   */
  private static boolean isHoliday(LocalDate date) {
    // 静态假日列表
    Set<LocalDate> holidays = getHolidays();
    return holidays.contains(date);
  }

  /**
   * 返回一个静态假日列表。
   * @return
   */
  private static Set<LocalDate> getHolidays() {
    // 返回一个静态假日列表
    List<LocalDate> holidayList = Arrays.asList(
        LocalDate.of(2024, 1, 1), // 元旦
        LocalDate.of(2024, 1, 2), // 元旦补休
        LocalDate.of(2024, 1, 3), // 元旦补休
        LocalDate.of(2024, 1, 24), // 春节
        LocalDate.of(2024, 1, 25), // 春节
        LocalDate.of(2024, 1, 26), // 春节
        LocalDate.of(2024, 4, 4), // 清明节
        LocalDate.of(2024, 4, 5), // 清明节
        LocalDate.of(2024, 5, 1), // 劳动节
        LocalDate.of(2024, 6, 22), // 端午节
        LocalDate.of(2024, 6, 23), // 端午节
        LocalDate.of(2024, 6, 24), // 端午节
        LocalDate.of(2024, 9, 29), // 中秋节
        LocalDate.of(2024, 10, 1), // 国庆节
        LocalDate.of(2024, 10, 2), // 国庆节
        LocalDate.of(2024, 10, 3), // 国庆节
        LocalDate.of(2024, 10, 4), // 国庆节
        LocalDate.of(2024, 10, 5), // 国庆节
        LocalDate.of(2024, 10, 6), // 国庆节
        LocalDate.of(2024, 10, 7) // 国庆节
    );
    return new HashSet<>(holidayList);
  }

  /**
   * 找到给定日期之后的第一个工作日。
   * @param date
   * @return
   */
  private static LocalDate getNextWorkingDay(LocalDate date) {
    LocalDate nextDay = date.plusDays(1);
    while (nextDay.getDayOfWeek() == DayOfWeek.SATURDAY ||
        nextDay.getDayOfWeek() == DayOfWeek.SUNDAY ||
        isHoliday(nextDay)) {
      nextDay = nextDay.plusDays(1);
    }
    return nextDay;
  }

}
